package com.huawei.esdk.tp.device.terminal;

import org.apache.log4j.Logger;

import com.huawei.esdk.platform.common.MessageContext;
import com.huawei.esdk.platform.common.ThreadLocalHolder;
import com.huawei.esdk.platform.common.exception.SDKException;
import com.huawei.esdk.platform.commu.itf.ISDKProtocolAdapter;
import com.huawei.esdk.platform.exception.ProtocolAdapterException;
import com.huawei.esdk.platform.nemgr.itf.IDevice;
import com.huawei.esdk.tp.common.ErrInfo;
import com.huawei.esdk.tp.common.constants.InfoKeys;
import com.huawei.esdk.tp.device.aa.TerminalAAService;
import com.huawei.esdk.tp.device.base.TPDeviceConnectionBase;

public class TerminalConnection extends TPDeviceConnectionBase
{
    private static final Logger LOGGER = Logger
            .getLogger(TerminalConnection.class);

    protected Object proxy;

    private TerminalAAService terminalAAService;

    public TerminalConnection(ISDKProtocolAdapter protocolAdapter,
            Object proxy, String user, String pwd)
    {
        super(user, pwd);
        this.proxy = proxy;
        this.terminalAAService = new TerminalAAService(protocolAdapter);
    }

    public IDevice getDevice()
    {
        return (IDevice) proxy;
    }

    @Override
    public Object getServiceProxy(Class<?>[] itfs) throws SDKException
    {
        prepareForSessionId((String)getAdditionalData("connId"));
        return this.proxy;
    }

    @Override
    public boolean doHeartbeat(String connId)
    {
        try
        {
            prepareForSessionId(connId);

            String res = terminalAAService.terminalKeepAlive();
            if (res != null && res.contains("\"success\":1"))
            {
                return true;
            }
        }
        catch (ProtocolAdapterException e)
        {
            LOGGER.error("", e);
        }
        catch (SDKException e)
        {
            return false;
        }

        return false;
    }

    @Override
    public boolean initConn(String connId)
    {
        try
        {
            // replace session before log
            String logMessage = connId;
            if (null != logMessage)
            {
                String exp = logMessage.substring(0, logMessage.length()/2);
                StringBuffer rep = new StringBuffer();
                for (int i=0; i<exp.length(); i++)
                {
                    rep.append("*");
                }
                logMessage = logMessage.replace(exp, rep);
            }
            LOGGER.debug("terminal initConn " + logMessage);
            prepareSessionId(connId);
            terminalAAService.terminalLoginRequest();
            // after LoginRequest, save Terminal Session. edit by taochunlong
            MessageContext mc = ThreadLocalHolder.get();
            setSession((String) mc.getEntities().get(
                    InfoKeys.TERMINAL_SESSION_ID.toString()));

            String authRes = terminalAAService.terminalAuthorize(
                    getLoginUser(), getLoginPassword());
            if (authRes != null && authRes.contains("\"success\":1"))
            {
                return true;
            }
        }
        catch (ProtocolAdapterException e)
        {
            LOGGER.error("", e);
        }

        return false;
    }

    @Override
    public void destroyConn(String connId)
    {
        try
        {
            prepareForSessionId(connId);
        }
        catch (SDKException e)
        {
            return;
        }

        terminalAAService.terminalLogout();
    }

    @Override
    public int getKeepAliveTimes()
    {
        return 3;
    }

    @Override
    public int getKeepAlivePeriod()
    {
        return 50;
    }

    public void prepareForSessionId(String connId) throws SDKException
    {
        super.prepareSessionId(connId);
        MessageContext mc = ThreadLocalHolder.get();
        if (null != getSession())
        {
            mc.getEntities().put(InfoKeys.TERMINAL_SESSION_ID.toString(),
                    getSession());
        }
        else
        {
            SDKException ex = new SDKException("");
            ex.setSdkErrCode(ErrInfo.AUTHORIZE_ERRORCODE);
            throw ex;
        }
    }
}
